import { APIResult } from '@/requestErrorConfig';
import { Form } from 'antd';
import { useState, useEffect } from 'react';
import { decrypt } from './crypto';

export default <T = any, P = any, Y = any>({
  fetchApi,
  updateStatusApi,
  extraParamsInfo,
  immediate = true,
  initValues = {},
}: {
  fetchApi?: (data: API.PageParams & P) => Promise<APIResult<{ list: T[]; count: number }>>;
  updateStatusApi?: (data: Y) => Promise<APIResult>;
  extraParamsInfo?: P;
  immediate?: boolean;
  initValues?: Record<string, any>;
}) => {
  const [form] = Form.useForm();
  const [searchParams, setSearchParams] = useState<any>({});
  const [extraParams, setExtraParams] = useState<any>(extraParamsInfo);

  const [page, setPage] = useState(1);
  const [pageSize] = useState(10);
  const [loading, setLoading] = useState(false);
  const [total, setTotal] = useState<number | undefined>(undefined);
  const [datasource, setDatasource] = useState<T[]>([]);

  const getDataList = async (
    pageInfo: API.PageParams,
    searchParams: P,
    extraParams: P | undefined,
  ) => {
    if (fetchApi === undefined) return;
    if (loading) {
      return;
    }
    setLoading(true);
    const { rsCode, body } = await fetchApi({
      ...pageInfo,
      ...searchParams,
      ...extraParams,
    });
    setLoading(false);
    if (rsCode === '00000000') {
      if (typeof body === 'string') {
        const data = decrypt(body);
        setDatasource(data.list);
        setTotal(data.count);
      } else {
        setDatasource(body.list);
        setTotal(body.count);
      }
      setSearchParams({ ...searchParams });
    }
  };

  useEffect(() => {
    if (immediate) {
      setSearchParams({ ...initValues });
      getDataList({ pageNo: page, pageSize, ...initValues }, searchParams as P, extraParams as P);
    }
  }, []);

  const updateStatus = async (record: Y) => {
    if (updateStatusApi === undefined) return;
    setLoading(true);
    const { rsCode } = await updateStatusApi(record);
    setLoading(false);
    if (rsCode === '00000000') {
      getDataList({ pageNo: page, pageSize }, searchParams, extraParams);
    }
  };
  const onFinish = (v: any) => {
    setPage(1);
    getDataList({ pageNo: 1, pageSize }, v, extraParams);
  };

  const onPageChange = (p: number) => {
    setPage(p);
    getDataList({ pageNo: p, pageSize }, { ...searchParams }, { ...extraParams });
  };

  return {
    loading,
    form,
    datasource,
    page,
    pageSize,
    total,
    onFinish,
    onPageChange,
    updateStatus,
    setExtraParams,
    setPage,
    setTotal,
    setLoading,
  };
};
